package com.romotc.test;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public abstract class FullCache<T extends AbstractId> {
    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    private final Lock readLock = lock.readLock(); // 读锁
    private final Lock writeLock = lock.writeLock(); // 写锁

    private List<T> cachedList = null; // 持有缓存的数据，若为null，表示缓存失效
    
  //对于clearCache()方法，由于其是一个写操作，故定义如下：
    public void clearCache() {
        writeLock.lock();
        cachedList = null;
        writeLock.unlock();
    }
    //对于get方法，由于是读操作，同时要考虑在缓存失效的情况下更新数据，其实现就稍微复杂一点：
    public List<T> getCachedList() {
        // 获得读锁:
        readLock.lock();
        try {
            if(cachedList==null) {
                // 在获得写锁前，必须先释放读锁:
                readLock.unlock();
                writeLock.lock();
                try {
                    cachedList = doGetList(); // 获取真正的数据
                }
                finally {
                    // 在释放写锁前，先获得读锁:
                    readLock.lock();
                    writeLock.unlock();
                }
            }
            return cachedList;
        }
        finally {
            // 确保读锁在方法返回前被释放:
            readLock.unlock();
        }
    }
    
	abstract List<T> doGetList();
}
